<template>
  <div class="ek-select-tree">
    <el-tree-select
      v-model="value"
      :data="ekOptions"
      :props="treeConfig.defaultProps"
      :check-strictly="treeConfig.checkStrictly"
      :check-on-click-node="treeConfig.checkOnClickNode"
      :show-checkbox="treeConfig.showCheckbox"
      :node-key="treeConfig.nodeKey"
      :lazy="treeConfig.lazy"
      :load="handleLoad"
      :multiple="multiple"
      filterable
      @blur="blur"
      @focus="focus"
      @change="change"
      @clear="clear"
      :loading="loading"
      loading-text="加载中"
      no-data-text="无数据"
      :placeholder="placeholder"
      :disabled="disabled"
      :clearable="clearable"
      :collapse-tags="collapseTags"
      :collapse-tags-tooltip="collapseTagsTooltip"
      :remote="remote"
      :size="size"
    >
    </el-tree-select>
  </div>
</template>

<script setup>
import {
  defineComponent,
  defineEmits,
  onMounted,
  getCurrentInstance,
  computed,
  ref,
  watch,
  reactive,
} from "vue";
import { arrayToTree } from "@/utils/common";

const props = defineProps({
  modelValue: {
    type: [String, Number, Array, Boolean],
    default: "",
  },
  //选项，选项里面必须包含label和value
  options: {
    type: Array,
    default: () => [],
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
  // 禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 是否显示清除
  clearable: {
    type: Boolean,
    default: true,
  },
  // 默认显示
  placeholder: {
    type: String,
    default: "请选择",
  },
  // 初始化请求接口
  autoInit: {
    type: Boolean,
    default: false,
  },
  // 搜索开启远程
  remote: {
    type: Boolean,
    default: false,
  },
  // 远程地址,存在远程地址
  url: {
    type: String,
    default: "",
  },
  collapseTags: {
    type: Boolean,
    default: true,
  },
  collapseTagsTooltip: {
    type: Boolean,
    default: true,
  },
  // 树形配置
  treeConfig: {
    type: Object,
    default: {},
  },
  size: {
    type: String,
    default: 'default'
  }
});

const {
  appContext: {
    config: { globalProperties },
  },
} = getCurrentInstance();

const { $http } = globalProperties;

const emit = defineEmits([
  "update:modelValue",
  "blur",
  "focus",
  "change",
  "clear",
]);

const value = computed({
  get() {
    if (props.multiple) {
      return props.modelValue;
    } else {
      return props.modelValue;
    }
  },
  set(value) {
    if (props.multiple) {
      emit("update:modelValue", value);
    } else {
      emit("update:modelValue", value);
    }
  },
});

// 选项列表
const ekOptions =  computed(() => {
  if(props.url){
    return remoteData.value;
  } else {
    return  arrayToTree(props.options)
  }
});
// 加载中
let loading = ref(false);
// 是否已经加载过
let loaded = ref(false);
// 树结构配置
let treeConfig = computed(()=>{
  return {
    defaultProps: {
      children: "children",
      label: "label",
      isLeaf: "leaf",
      disabled: "disabled",
      class: "class",
    },
    // 选择任意级别
    checkStrictly: false,
    // 点击节点选中
    checkOnClickNode: false,
    // 是否显示复选框
    showCheckbox: false,
    // 主键
    nodeKey: "id",
    // 开启懒加载
    lazy: false,

    fieldMapping: {
      label:["label"],
      id: "id",
      parentId: "parent_id",
    },
    ...props.treeConfig
  }
}) 
// 取数据的模型编码

let fieldMapping = treeConfig.value.fieldMapping;

let url = props.url;

// 获取远程数据
const remoteData = ref([]);

function init(isFocus = false) {
  // 存在远程地址，开启初始化获取数据或者存在值
  if (url) {
    if (isFocus || props.autoInit || (value.value || value.value === 0) || value.value?.length) {
      // 开启懒加载
      if (treeConfig.value.lazy) {
        // 懒加载获取数据
        initLazy();
      } else {
        // 一次性获取数据
        getTreeData(url);
      }
    }
  } 
}
init(false);
// 获取下拉列表
function getTreeData(url) {
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  $http.post(url).then((res) => {
    if (res.status === 'success')  {
      let tree = res.data?.length ? res.data : [];
      if (tree.length) {
        tree = setMappingData(fieldMapping, tree);
      }
      remoteData.value = arrayToTree(tree);
      loaded.value = true;
      loading.value = false;
    }
  });
}
/* 开启懒加载，使用foucs触发懒加载初始化 */
function initLazy() {
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  $http
    .post(url, {
      type: "lazy",
      parentId: "",
    })
    .then((res) => {
      let tree = res.data?.length ? res.data : [];
      if (tree.length) {
        tree = setMappingData(fieldMapping, tree);
      }
      remoteData.value = arrayToTree(tree);
      loaded.value = true;
      loading.value = false;
    });
}
// 懒加载
function handleLoad(node, resolve, reject) {
  // 没有开启自动初始化，且没有加载过，不执行；因为el-tree 初始化会执行该方法
  if (!loaded.value) {
    return;
  }
  $http
    .post(url, {
      type: "lazy",
      parentId: node.data.id,
    })
    .then((res) => {
      let tree = res.data;
      if (tree.length) {
        tree = setMappingData(fieldMapping, tree);
      }
      resolve(tree);
    });
}
function setMappingData(mapping, data) {
  for (let i in mapping) {
    let val = mapping[i];
    for (let j in data) {
      let labelArr = [];
      if(i === 'label'){
        for (let i in val) {
          labelArr.push(data[j][val[i]]);
        }
        data[j][i] = labelArr.join("-");
      } else {
        data[j][i] = data[j][val];
      }
    }
  }
  return data;
}
// 失去焦点
function blur(event) {
  emit("blur", event);
}
// 聚焦
function focus(event) {
  init(true);
  emit("focus", event);
}
// 改变事件
function change(event) {
  emit("change", event);
}
// 清除事件
function clear() {;
  emit("clear");
}

// todo 远程搜索 

// todo 懒加载默认显示问题
</script>

<style scoped lang="scss"></style>
